package jp.co.toshiba.ffsa.service.csas;

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.sql.Timestamp;
import java.util.Calendar;

import jp.co.toshiba.ffsa.common.MakeHash;
import jp.co.toshiba.ffsa.entity.User;
import jp.co.toshiba.ffsa.mail.SendMaiMail;
import jp.co.toshiba.ffsa.service.common.ConstantValue;

import org.seasar.extension.jdbc.JdbcManager;
import org.seasar.extension.jdbc.where.SimpleWhere;
import org.seasar.framework.container.SingletonS2Container;
import org.seasar.framework.container.factory.SingletonS2ContainerFactory;
import org.seasar.mai.mail.MailAddress;
import org.seasar.struts.util.MessageResourcesUtil;

import com.ozacc.mail.MailSendException;

/**
 *ID入力Serviceクラス
 * @author npc
 */
public class Csas501Service {
    /** メールアドレス */
    private String emailAddress;
    /** FirstName */
    private String firstName;
    /** LastName */
    private String lastName;
    /** UserID */
    private String userID;
    /** 仮パスワード */
    private String tmpPassword;
    /** 仮パスワード桁数 */
    protected final static int pwKeitasuu = 8;
    /** メール送信種別 */
    protected final static int meilType = 1;

    protected final static String CANDIDATE1 = "abcdefghjkmnprstuwxyz";
    protected final static String CANDIDATE2 = "ACDEFGHJKLMNPQRSTUWXY";
    protected final static String CANDIDATE3 = "1234567890";

    /** 旧パスワードのユーザーマスタ */
    private User user = null;

    /**
     * メールアドレスをセットする
     * @param emailAddress
     */
    public void setEmailAddress(String emailAddress){this.emailAddress = emailAddress;}
    /**
     * firstNameをセットする
     * @param firstName
     */
    public void setFirstName(String firstName){this.firstName = firstName;}
    /**
     * firstNameをセットする
     * @param firstName
     */
    public void setLastName(String lastName){this.lastName = lastName;}
    /**
     * tmpPasswordをセットする
     * @param tmpPassword
     */
    public void setTmpPassword(String tmpPassword) {
        this.tmpPassword = tmpPassword;
    }
    /**
     * UserIDをセットする
     * @param UserID
     */
    public void setUserID(String userID) {
        this.userID = userID;
    }
    /**
     * メールアドレスを取得する
     * @return emailAddress
     */
    public String getEmailAddress(){return this.emailAddress;}
    /**
     * firstNameを取得する
     * @return firstName
     */
    public String getFirstName(){return this.firstName;}
    /**
     * lastNameを取得する
     * @return lastName
     */
    public String getLastName(){return this.lastName;}
    /**
     * tmpPasswordを取得する
     * @return tmpPassword
     */
    public String getTmpPassword() {
        return this.tmpPassword;
    }
    /**
     * ユーザーIDを取得する
     * @return userID
     */
    public String getUserID(){return this.userID;}

    /**
     * 存在チェック処理
     * @return 存在チェック結果
     * @throws Exception エラー
     */
    public Boolean checkUserPresence( ) throws Exception {
        Boolean bflg = false;

        if (getFaqInfo().length() > 0){
            bflg = true;
        }

        return bflg;
    }

    /**
     *  ユーザー情報件数取得
     *
     * @param emailAddress
     * @param firstName
     * @param fastName
     * @return
     * @throws Exception エラー
     */
    public String getFaqInfo() throws Exception {
        // データ件数
        String strUserID = "";

        // S2Container初期化
        SingletonS2ContainerFactory.init();
        // S2ContainerからJdbcManagerを取得
        JdbcManager jdbcManager = SingletonS2Container.getComponent(JdbcManager.class);
        try{
            // 検索条件
            SimpleWhere swh = new SimpleWhere().eq("mailAddress", this.emailAddress)
                                               .eq("firstName", this.firstName)
                                               .eq("lastName", this.lastName)
                                               .eq("deleteFlag", "0");

            // 一覧取得
            user = jdbcManager.from(User.class)
                                     .where(swh)
                                     .getSingleResult()
                                     ;
            if(user != null){
                strUserID = user.userID;
                userID = user.userID;
            }

            return strUserID;

        }catch(Exception e){
            throw e;
        }
    }


    /**
     * 仮パスワード発行処理
     * @return 処理結果
     * @throws Exception エラー
     */
    public String tmpPasswordIssued( ) throws Exception {
        String strTmpPassword = "";

        strTmpPassword = makePassWord(pwKeitasuu);
        tmpPassword = strTmpPassword;
        // 仮パスワードを更新
        updateTmpPassword();

        return strTmpPassword;

   }

    /**
     * UPDATE処理
     * @throws Exception エラー
     */
    public void updateTmpPassword( ) throws Exception {
        // S2Container初期化
        SingletonS2ContainerFactory.init();
        // S2ContainerからJdbcManagerを取得
        JdbcManager jdbcManager = SingletonS2Container.getComponent(JdbcManager.class);
        try{
            // 当日取得
            Calendar cal = Calendar.getInstance();
            Timestamp timSystime = new Timestamp(cal.getTime().getTime());

            // パラメータ値設定
            User param = new User();
            param.userID              = this.userID;
            param.passwordHistroty3   = user.passwordHistroty2;
            param.passwordHistroty2   = user.passwordHistroty1;
            param.passwordHistroty1   = user.password;
            param.password            = MakeHash.getSha256HashCode(this.tmpPassword);
            param.passwordUpdateAt    = timSystime;
            param.updatedBy           = this.userID;
            param.updatedAt           = timSystime;

            jdbcManager.updateBySqlFile(
                            "data/updTmpPwd.sql",
                            param)
                            .execute();

        }catch(Exception e){
            throw e;
        }
    }

    /**
     * メール送信処理
     * @return 処理結果
     * @throws Exception エラー
     */
    public Boolean mailSend( ) throws Exception {
        boolean successFlag = false;
        try {
            // メール情報をセット
            SendMaiMail sendMaiMail = new SendMaiMail();

            // 送信元メールアドレス(From)
            String mailAddressFrom = MessageResourcesUtil.getMessage("mail_address_from");
            sendMaiMail.setMailAddressFrom(mailAddressFrom);

            // 送信先メールアドレス(To)
            MailAddress[] sendMailAddressTo = new MailAddress[1];
            sendMailAddressTo[0] = new MailAddress(emailAddress,"");

            sendMaiMail.setMailAddressTo(sendMailAddressTo);

            // ユーザー名
            sendMaiMail.setReplacementItem1(firstName + " " + lastName);
            // 仮パスワード
            sendMaiMail.setReplacementItem2(tmpPassword);

            // 送信
            successFlag = sendMaiMail.sendMail(ConstantValue.tmpPwdMail);

            if(!successFlag){
                return false;
            }

        }catch(MailSendException m){
            return false;
        }catch(Exception e){
            e.printStackTrace();
            throw e;
        }
        return true;

    }

    /**
     * ランダムな英数字からなる指定サイズの文字列を返す
     * @param size 文字列のサイズ
     * @return str 生成された文字列
     */
    public String randomPassword(int size){
        SecureRandom random = new SecureRandom();
        char[] pass = new char[size];
        for(int i=0; i<pass.length; i++){
            switch(random.nextInt(3)){
                case 0: // 'a' - 'z'
                pass[i] = (char)(97 + random.nextInt(26));
                break;
                case 1: // 'A' - 'Z'
                pass[i] = (char)(65 + random.nextInt(26));
                break;
                case 2: // '0' - '9'
                pass[i] = (char)(48 + random.nextInt(10));
                break;
                default:
                pass[i] = 'a';
            }
        }
        // 文字の配列を文字列に変換
        return new String(pass);
    }

    /**
     * パスワードを返す
     * @param keta 作成桁数
     * @return パスワード
     */
    public String makePassWord(int keta){
        char[] generated = new char[keta];
        String candidateAll = "";
        int watermark = 0;
        String[] candidates = new String[]{CANDIDATE1,CANDIDATE2,CANDIDATE3};
        int max = candidates.length;
        try{
            SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
            if(keta<candidates.length){
                max = keta;
            }
            // それぞれのパートから最低1文字を選択する.
            for(int i=0; i<max; i++){
                if(candidates[i] != null && !"".equals(candidates[i])){
                    generated[watermark++] = candidates[i].charAt(sr.nextInt(candidates[i].length()));
                    candidateAll += candidates[i];
                }
            }
            // すべてのパートから残りの文字を決定する.
            for(int i=watermark; i < keta; i++){
                generated[i] = candidateAll.charAt(sr.nextInt(candidateAll.length()));
            }
            // 一定以上まぜる
            for(int i=100000; i>=0; i--){
                int x = sr.nextInt(keta);
                int y = sr.nextInt(keta);
                char tmp = generated[x];
                generated[x] = generated[y];
                generated[y] = tmp;
            }
        }catch(NoSuchAlgorithmException ex){
            ex.printStackTrace();
        }
        return new String(generated);
    }

}
